package com.huiquan.vocab.service;

import com.huiquan.analysis.domain.User;
import com.huiquan.foundation.constant.SubmitStatus;
import com.huiquan.framework.base.BaseService;
import com.huiquan.framework.base.ReturnCode;
import com.huiquan.framework.base.ReturnData;
import com.huiquan.framework.constant.BaseContants;
import com.huiquan.framework.utils.GetListUtil;
import com.huiquan.framework.utils.ReturnUtil;
import com.huiquan.synonymy.dao.SynonymyWordDao;
import com.huiquan.vocab.dao.VocabDyadDao;
import com.huiquan.vocab.dao.VocabDyadPositionDao;
import com.huiquan.vocab.dao.VocabDyadStdDao;
import com.huiquan.vocab.dao.VocabElementDao;
import com.huiquan.vocab.domain.VocabDyadPosition;
import com.huiquan.vocab.domain.VocabDyadPre;
import com.huiquan.vocab.domain.VocabDyadStd;
import com.huiquan.vocab.domain.VocabElement;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.ModelAndView;

import java.util.*;

@Service
public class VocabDyadPositionService extends BaseService {

	@Autowired
	private VocabDyadPositionDao vocabDyadPositionDao;
	@Autowired
	private SynonymyWordDao synonymyWordDao;
	@Autowired
	private VocabDyadStdDao vocabDyadStdDao;
	@Autowired
	private VocabDyadDao vocabDyadDao;

	public ModelAndView list(String startStr, String oKey, String exactSearchFlag, String countPerPageStr,String orderByCnt) {

		Map<String, Object> param = new HashMap<>();
		if (oKey != null && !oKey.isEmpty()) {
			if (exactSearchFlag != null && exactSearchFlag.equals("1")) {
				param.put("oStd", oKey);
			} else {
				param.put("oStd", "%" + oKey + "%");
			}
		}
		if(StringUtils.isNotBlank(orderByCnt)){
			param.put("orderByCnt",orderByCnt);
		}
		int totalSize = vocabDyadPositionDao.retrieveSize(param);
		LOGGER.info("List total size=" + totalSize);

		Map<String, Integer> pageNo;
		if (countPerPageStr == null || countPerPageStr.isEmpty()) {
			countPerPageStr = "20";
		}
		int countPerPage = Integer.parseInt(countPerPageStr);
		pageNo = GetListUtil.getPageNoParam(totalSize, startStr, countPerPage);
		param.put("countPerPage", countPerPage);

		int endPage = pageNo.get("endPage");
		int start = pageNo.get("start");
		int startIndex = pageNo.get("startIndex");

		List<String> list = new ArrayList<>();
		if (startIndex < totalSize) {
			param.put("startIndex", startIndex);
			list = vocabDyadPositionDao.retrieveOStdList(param);
		}

		List<VocabDyadPosition> resultList = new ArrayList<>();
		if (!list.isEmpty()) {
			// 根据p在左还是在右将数据维护在dto中
			resultList = getResultByStdList(list);
		}

		Map<String, String> showSearch = new LinkedHashMap<>();
		showSearch.put("oKey", "O");

		Map<String, Object> map = GetListUtil.getReturnMap2(totalSize, start, startIndex, endPage, resultList, null);
		map.put("showSearch", showSearch);
		List<String> stdList = vocabDyadPositionDao.checkStdFlag();
		StringBuffer err = new StringBuffer();
		if (stdList != null && stdList.size() > 0) {
			for (String std : stdList) {
				if (err.length() == 0) {
					err.append("存在错误的二元组:" + std + ";");
				} else {
					err.append(std + ";");
				}
			}
		}
		if (err.length() > 0) {
			map.put("checkStd", err.toString());
		}
		return new ModelAndView("vocab/dyad_index", map);
	}

	private List<VocabDyadPosition> getResultByStdList(List<String> list) {
		List<VocabDyadPosition> resultList = new ArrayList<>();
		List<VocabDyadPosition> leftList = new ArrayList<>();
		List<VocabDyadPosition> rightList = new ArrayList<>();
		VocabDyadPosition addValue = new VocabDyadPosition();
		for (String oStd : list) {
			leftList.clear();
			rightList.clear();
			List<VocabDyadPosition> allValues = vocabDyadPositionDao.retrieveListByOStd(oStd);
			for (VocabDyadPosition value : allValues) {
				String[] pArr = value.getP().split((char) 1 + "");
				String[] arr = value.getArray().split((char) 1 + "");
				List<Map<String, String>> pList = new ArrayList<>();
				Map<String, String> pAndArr = new HashMap<>();
				for (int i = 0; i < pArr.length; i++) {
					if (pAndArr.get(pArr[i]) == null) {
						pAndArr.put(pArr[i], arr[i] + "\n");
					} else {
						pAndArr.put(pArr[i], pAndArr.get(pArr[i]) + arr[i] + "\n");
					}
				}
				for (String key : pAndArr.keySet()) {
					Map<String, String> pMap = new HashMap<>();
					pMap.put("p", key);
					pMap.put("array", pAndArr.get(key));
					if (StringUtils.equals(value.getDisplayP(), key)) {
						pList.add(0, pMap);
					} else {
						pList.add(pMap);
					}
				}
				value.setpList(pList);
				if (StringUtils.isNotBlank(value.getSentence())) {
					String sentence = value.getSentence().replace((char) 1 + "", "\n");
					if (value.getSentence().split((char) 1 + "").length > 0) {
						value.setShowSentence(value.getSentence().split((char) 1 + "")[0]);
					}
					value.setSentence(sentence);
				} else {
					value.setSentence("");
					value.setShowSentence("");
				}
				if (value.getRightP() == 1) {
					rightList.add(value);
				} else {
					leftList.add(value);
				}
			}
			List<VocabDyadPosition> subList = new ArrayList<>();
			int num = 0;
			if (leftList.size() > rightList.size()) {
				num = leftList.size();
			} else {
				num = rightList.size();
			}
			for (int i = 0; i < num; i++) {
				VocabDyadPosition value = new VocabDyadPosition();
				if (leftList.size() > i) {
					value.setLeft(leftList.get(i));
				}
				if (rightList.size() > i) {
					value.setRight(rightList.get(i));
				}
				subList.add(value);
			}
			addValue = new VocabDyadPosition();
			addValue.setSubList(subList);
			if (leftList.size() > rightList.size()) {
				addValue.setNum(leftList.size());
			} else {
				addValue.setNum(rightList.size());
			}
			addValue.setoStd(oStd);
			resultList.add(addValue);
		}

		return resultList;
	}

	public ReturnData init() {

		if (!SubmitStatus.getSubmitRecords().contains(SubmitStatus.TYPE_DYAD_O_CHECK_P_INIT)) {

			// 刷新二元组位置判断为运行中
			SubmitStatus.addSubmitRecords(SubmitStatus.TYPE_DYAD_O_CHECK_P_INIT);

			// 初始化o和oa合并后的同义词表
			synonymyWordDao.initOOaSynonym();

			vocabDyadPositionDao.init();

			SubmitStatus.removeSubmitRecords(SubmitStatus.TYPE_DYAD_O_CHECK_P_INIT);
		}

		return ReturnUtil.success();
	}

	@Autowired
	private VocabElementDao vocabElementDao;

	public ReturnData changeElementSynonym(String id, String ElementSynonym, User user) {

		// 校验替换的词语是否是正确的o
		Map<String, Object> param = new HashMap<>();
		param.put("flag", 0);
		param.put("vocabulary", ElementSynonym);
		param.put("property", "o");
		List<VocabElement> list = vocabElementDao.retrieveList(param);

		if (list == null || list.isEmpty()) {
			ReturnCode rc = ReturnCode.DYNAMIC_DESC_EXCEPTION;
			rc.setDesc("该元素不是正确的o");
			return ReturnUtil.fail(rc);
		}

		// 更改元素同义词
		vocabDyadPositionDao.changeElementSynonym(id, ElementSynonym, user);

		return ReturnUtil.success();
	}

	public ReturnData submitPage(String oStd, User user) {

		// 批量修改为已校验
		vocabDyadPositionDao.batchUpdateCheckFlag(oStd, user);

		return ReturnUtil.success();
	}

	public ReturnData changeDisplayP(String id, String displayP, User user) {

		// 更改元素同义词
		vocabDyadPositionDao.changeDisplayP(id, displayP);
		// 提交该条
		vocabDyadPositionDao.updateCheckFlag(id, user);
		return ReturnUtil.success();
	}

	public ReturnData submitDyad(String o, String p, String position, String elementSynonym, User user) {

		p = "," + p + ",";
		String array = p;
		String partPattern = ",";
		elementSynonym = elementSynonym == null ? "" : elementSynonym;

		for (int i = 0; i < p.split(",").length - 1; i++) {
			partPattern += "p,";
		}
		if (position.equals("left")) {
			partPattern += "o,";
			array += o + ",";
		} else {
			partPattern = ",o" + partPattern;
			array = "," + o + array;
		}

		// 查找该二元组是否已存在，已存在在返回提示，不存在则添加新数据
		VocabDyadPre dyad = vocabDyadDao.retrieveByDyadProperties("p+o", array, partPattern);

		if (dyad != null) {
			// 判断该方位词判断是否存在
			Map<String, Object> param = new HashMap<>();
			param.put("array", array);
			param.put("partPattern", partPattern);
			int cnt = vocabDyadPositionDao.checkPositionByArray(param);
			if (cnt == 0) {
				//判断是否有该组
				param.clear();
				param.put("oStd", o);
				param.put("dyadStdId", dyad.getStdId());
				param.put("rightP", position.equals("left") ? 0 : 1);
				long positionId = vocabDyadPositionDao.getPosition(param);
				VocabDyadPosition op = new VocabDyadPosition();
				if(positionId==0){
					op.setDyadStdId(dyad.getStdId());
					op.setArray(array);
					op.setPartPattern(partPattern);
					op.setAddFlag(BaseContants.FLAG_YES);
					op.setO(o);
					op.setoStd(o);
					op.setModifierId(user.getUserId());
					op.setRightP(position.equals("left") ? 0 : 1);
					op.setDisplayP(p);
					op.setDyadId(dyad.getId());
					op.setDisplayFlag(BaseContants.FLAG_YES);
					op.setP(p);
					positionId = vocabDyadPositionDao.insert(op);
				}
				op.setPositionId(positionId);
				vocabDyadPositionDao.insertVocabulary(op);
			} else {
				ReturnCode rc = ReturnCode.DYNAMIC_DESC_EXCEPTION;
				rc.setDesc("该二元组已存在，标准词为：" + array);
				return ReturnUtil.fail(rc);
			}
		} else {
			VocabDyadStd std = new VocabDyadStd();
			std.setType("p+o");
			std.setArray(array);
			std.setPartPattern(partPattern);
			std.setElementSynonym(elementSynonym);
			std.setOrderVocabulary(o);
			// 维护std_array
			dealStdArray(std, array, partPattern);

			Long stdId = vocabDyadStdDao.insert(std);

			std.setStdId(stdId);
			Long dyadId = vocabDyadDao.insert(std);

			VocabDyadPosition op = new VocabDyadPosition();
			op.setDyadStdId(stdId);
			op.setArray(array);
			op.setPartPattern(partPattern);
			op.setAddFlag(BaseContants.FLAG_YES);
			op.setO(o);
			op.setoStd(o);
			op.setModifierId(user.getUserId());
			op.setRightP(position.equals("left") ? 0 : 1);
			op.setDisplayP(p);
			op.setDyadId(dyadId);
			op.setDisplayFlag(1);
			op.setP(p);
			Long positionId = vocabDyadPositionDao.insert(op);
			op.setPositionId(positionId);
			vocabDyadPositionDao.insertVocabulary(op);

		}

		return ReturnUtil.success();
	}

	private void dealStdArray(VocabDyadStd std, String array, String partPattern) {
		String[] property = partPattern.substring(1, partPattern.length()).split(",");
		String[] arrayArr = array.substring(1, array.length()).split(",");
		StringBuffer stdArr = new StringBuffer();
		stdArr.append(",");
		for (int i = 0; i < property.length; i++) {
			Map<String, Object> param = new HashMap<>();
			param.put("property", property[i]);
			param.put("word", arrayArr[i]);
			List<String> valueList = synonymyWordDao.getStdByWord(param);
			if (valueList != null && valueList.size() > 0) {
				stdArr.append(valueList.get(0)).append(",");
			} else {
				stdArr.append(arrayArr[i]).append(",");
			}
		}
		std.setStdArray(stdArr.toString());
	}

	public ReturnData delStd(String id) {

		// 判断是否是添加的二元组~如果是添加的则把二元组放入错误中
		// VocabDyadOCheckP value =
		// vocabDyadPositionDao.retrieveObjectById(Long.parseLong(id));
		// if(value.getAddFlag() == 1){
		// VocabDyadStd param = new VocabDyadStd();
		// param.setId(value.getDyadStdId());
		// param.setFlag(1);
		// vocabDyadStdDao.update(param);
		// }

		vocabDyadPositionDao.deleteById(Long.parseLong(id));

		return ReturnUtil.success();
	}

	public ReturnData changeDisplayFlag(String id, String displayFlag, User user) {

		vocabDyadPositionDao.changeDisplayFlag(id, displayFlag, user);

		return ReturnUtil.success();
	}

}
